package com.jinzhi.jzweb.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.jinzhi.api.exception.IFastApiException;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.Result;
import com.jinzhi.jzapi.utils.HttpClientUtil;
import com.jinzhi.jzapi.utils.ITextPdfUtil;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.pojo.CertificatesExportVo;
import com.jinzhi.jzweb.pojo.CertificatesVo;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.jzweb.utils.ValuesUtil;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.*;

/**
 * <pre>
 * X证书
 * </pre>
 * <small> 2020-02-24 21:00:11 | lance</small>
 */
@Controller
@RequestMapping("/jzweb/certificates")
public class CertificatesController extends BaseController {
    @Autowired
    private CertificatesService certificatesService;
    @Autowired
    private CertificationBatchService certificationBatchService;
    @Autowired
    private UserService userService;
    @Autowired
    private CertificateNewsService certificateNewsService;
    @Autowired
    private CertificateProfileService certificateProfileService;
    @Autowired
    private OrganizationNewsService organizationNewsService;

    @GetMapping()
    @RequiresPermissions("jzweb:certificates:certificates")
    String Certificates() {
        return "jzweb/certificates/certificates";
    }

    @ResponseBody
    @GetMapping("/list")
    @RequiresPermissions("jzweb:certificates:certificates")
    public Result<Page<CertificatesDO>> list(CertificatesDO certificatesDTO) {
        Wrapper<CertificatesDO> wrapper = new EntityWrapper<CertificatesDO>().orderBy("id", false);
        if (certificatesDTO.getState() != null) {
            wrapper.eq("state", certificatesDTO.getState());
        }
        if (certificatesDTO.getNumbers() != null) {
            wrapper.like("numbers", certificatesDTO.getNumbers());
        }
        if (certificatesDTO.getCertificateName() != null) {
            wrapper.like("certificate_name", certificatesDTO.getCertificateName());
        }
        if (StringUtils.isNotBlank(certificatesDTO.getUserName())) {
            Wrapper<UserDO> uWrapper = new EntityWrapper<UserDO>().like("name", certificatesDTO.getUserName());
            List<UserDO> userDOS = userService.selectList(uWrapper);
            String str = "";
            for (UserDO userDO : userDOS) {
                str = str + userDO.getId() + ",";
            }
            wrapper.and();
            if (StringUtils.isNotBlank(str)) {
                wrapper.in("user_id", str.substring(0, str.length() - 1));
            } else {
                wrapper.eq("user_id", null);
            }
        }

        Page<CertificatesDO> page = certificatesService.selectPage(getPage(CertificatesDO.class), wrapper);
        List list = new ArrayList();
        for (int i = 0; i < page.getRecords().size(); i++) {
            CertificatesDO obj = (CertificatesDO) page.getRecords().get(i);
            if (obj.getUserId() != null) {
                UserDO userDO = userService.selectById(obj.getUserId());
                if (userDO != null) {
                    obj.setUserName(userDO.getName());
                }
            }
            list.add(obj);
        }
        page.setRecords(list);
        return Result.ok(page);
    }

    @GetMapping("/add")
    @RequiresPermissions("jzweb:certificates:add")
    String add(Model model) {
        model.addAttribute("certificateProfile", certificateNewsService.selByNewId());
        return "jzweb/certificates/add";
    }

    @GetMapping("/edit/{id}")
    @RequiresPermissions("jzweb:certificates:edit")
    String edit(@PathVariable("id") Long id, Model model) {
        model.addAttribute("certificateProfile", certificateNewsService.selByNewId());
        CertificatesDO certificates = certificatesService.selectById(id);
        model.addAttribute("certificates", certificates);
        return "jzweb/certificates/edit";
    }

    @Log("添加X证书")
    @ResponseBody
    @PostMapping("/save")
    @RequiresPermissions("jzweb:certificates:add")
    public Result<String> save(CertificatesDO certificates) {
        if (certificates.getNewsId() != null) {
            CertificateNewsDO certificateNewsDO = certificateNewsService.selectById(certificates.getNewsId());
            if (certificateNewsDO != null) {
                CertificateProfileDO certificateProfileDO = certificateProfileService.selectById(certificateNewsDO.getProfileId());
                if (certificateProfileDO != null) {
                    if (certificateNewsDO.getGrade() == 0) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(高级)");
                    } else if (certificateNewsDO.getGrade() == 1) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(中级)");
                    } else if (certificateNewsDO.getGrade() == 2) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(初级)");
                    } else {
                        certificates.setCertificateName(certificateProfileDO.getName());
                    }
                }
            }
        }
        certificatesService.insert(certificates);
        return Result.ok();
    }

    @Log("修改X证书")
    @ResponseBody
    @RequestMapping("/update")
    @RequiresPermissions("jzweb:certificates:edit")
    public Result<String> update(CertificatesDO certificates) {
        if (certificates.getNewsId() != null) {
            CertificateNewsDO certificateNewsDO = certificateNewsService.selectById(certificates.getNewsId());
            if (certificateNewsDO != null) {
                CertificateProfileDO certificateProfileDO = certificateProfileService.selectById(certificateNewsDO.getProfileId());
                if (certificateProfileDO != null) {
                    if (certificateNewsDO.getGrade() == 0) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(高级)");
                    } else if (certificateNewsDO.getGrade() == 1) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(中级)");
                    } else if (certificateNewsDO.getGrade() == 2) {
                        certificates.setCertificateName(certificateProfileDO.getName() + "(初级)");
                    } else {
                        certificates.setCertificateName(certificateProfileDO.getName());
                    }
                }
            }
        }
        boolean update = certificatesService.updateById(certificates);
        return update ? Result.ok() : Result.fail();
    }

    @Log("删除X证书")
    @PostMapping("/remove")
    @ResponseBody
    @RequiresPermissions("jzweb:certificates:remove")
    public Result<String> remove(Long id) {
        certificatesService.deleteById(id);
        return Result.ok();
    }

    @Log("批量删除X证书")
    @PostMapping("/batchRemove")
    @ResponseBody
    @RequiresPermissions("jzweb:certificates:batchRemove")
    public Result<String> remove(@RequestParam("ids[]") Long[] ids) {
        certificatesService.deleteBatchIds(Arrays.asList(ids));
        return Result.ok();
    }

    @Log("查询认证批次")
    @GetMapping("/selAllCbatch")
    @ResponseBody
    public Result<?> selAllCbatch() {
        List<Map> allCbatch = certificatesService.selCbatchList();
        return Result.ok(allCbatch);
    }

    @Log("考点信息")
    @ResponseBody
    @GetMapping("/distributionOrgId")
    public Result<?> distributionOrgId(String cbatchId) {
        List<Map<Object, Object>> mapsre;
        //如选择了认证批次，则查询认证批次下的机构信息，如没有，则查询所有正常状态的机构信息
        if (StringUtils.isNotBlank(cbatchId)) {
            //查询认证批次信息
            CertificationBatchDO certificationBatchDO = certificationBatchService.selectById(Long.parseLong(cbatchId));
            mapsre = organizationNewsService.selCerOrgAll(certificationBatchDO.getProfileId().toString());
        } else {
            mapsre = organizationNewsService.selByOrgId();
        }

        return Result.ok(mapsre);
    }

    /**
     * 导出证书信息
     *
     * @param response
     */
    @Log("导出证书信息")
    @RequestMapping("/downloadImportTemplate")
    @RequiresPermissions("jzweb:certificates:import")
    @ResponseBody
    public void downloadImportTemplate(HttpServletRequest request, HttpServletResponse response, String cbatchId) {
        CertificationBatchDO certificationBatchDO = certificationBatchService.selectById(Long.parseLong(cbatchId));
        List<CertificatesExportVo> list = new LinkedList<>();
        List<CertificatesVo> certificatesVos = certificatesService.selExportAll(Long.parseLong(cbatchId));
        if (certificatesVos != null && certificatesVos.size() > 0) {
            for (CertificatesVo certificatesVo : certificatesVos) {
                CertificatesExportVo certificatesExportVo = new CertificatesExportVo();
                certificatesExportVo.setIdCard(certificatesVo.getIdCard());
                certificatesExportVo.setName(certificatesVo.getName());
                certificatesExportVo.setNumbers(certificatesVo.getNumbers());
                certificatesExportVo.setOrgName(certificatesVo.getOrgName());
                byte[] imageFromNetByUrl = HttpClientUtil.getImageFromNetByUrl(certificatesVo.getImageUrl());
                certificatesExportVo.setImageUrl(imageFromNetByUrl);
                certificatesExportVo.setProfileName(certificatesVo.getProfileName());
                list.add(certificatesExportVo);
            }

            //导出操作
            EasyPoiUtil.exportExcel(list, "获证考生信息", "获证考生信息", CertificatesExportVo.class, certificationBatchDO.getName() + "-获证考生表", response);
        } else {
            throw new IFastApiException(ApiEnumError.NOTBATCHSTU.getCodeStr());
        }
    }

    /**
     * 判断是否有数据
     */
    @Log("判断是否有数据")
    @RequestMapping("/isDataNull")
    @RequiresPermissions("jzweb:certificates:import")
    @ResponseBody
    public boolean isDataNull(HttpServletRequest request, HttpServletResponse response,String cbatchId, String orgId) {
        Map map = new HashMap();
        if (StringUtils.isNotBlank(cbatchId)) {
            map.put("cbatchId", Long.parseLong(cbatchId));
        }else{
            map.put("cbatchId", "");
        }
        if (StringUtils.isNotBlank(orgId)) {
            map.put("orgId", Long.parseLong(orgId));
        }else{
            map.put("orgId", "");
        }

        map.put("returnUrl", ValuesUtil.returnUrl);
        map.put("localUrl", ValuesUtil.localUrl);
        List<String> imgUrls = certificatesService.selImgUrls(map);
        if (imgUrls != null && imgUrls.size() > 0) {
            return true;
        }else {
            return false;
        }
    }

    /**
     * 导出证书PDF文件
     */
    @Log("导出证书PDF文件")
    @RequestMapping("/exportPdf")
    @RequiresPermissions("jzweb:certificates:import")
    @ResponseBody
    public void exportPdf(HttpServletRequest request, HttpServletResponse response,String cbatchId, String orgId) {
        Map map = new HashMap();
        CertificationBatchDO certificationBatchDO = null;
        if (StringUtils.isNotBlank(cbatchId)) {
            map.put("cbatchId", Long.parseLong(cbatchId));
            certificationBatchDO = certificationBatchService.selectById(Long.parseLong(cbatchId));
        }else{
            map.put("cbatchId", "");
        }
        OrganizationNewsDO organizationNewsDO = null;
        if (StringUtils.isNotBlank(orgId)) {
            map.put("orgId", Long.parseLong(orgId));
            organizationNewsDO = organizationNewsService.selectById(Long.parseLong(orgId));
        }else{
            map.put("orgId", "");
        }

        map.put("returnUrl", ValuesUtil.returnUrl);
        map.put("localUrl", ValuesUtil.localUrl);
        List<String> imgUrls = certificatesService.selImgUrls(map);
        if (imgUrls != null && imgUrls.size() > 0) {
            String pdfName;
            if(certificationBatchDO != null && organizationNewsDO != null){
                if(StringUtils.isNotBlank(certificationBatchDO.getName())){
                    if(StringUtils.isNotBlank(organizationNewsDO.getName())){
                        pdfName = certificationBatchDO.getName() +"(" + organizationNewsDO.getName() + ")-证书信息";
                    }else{
                        pdfName = certificationBatchDO.getName() + "-证书信息";
                    }
                }else{
                    if(StringUtils.isNotBlank(organizationNewsDO.getName())){
                        pdfName = organizationNewsDO.getName() + "-证书信息";
                    }else{
                        pdfName = "所有证书信息";
                    }
                }
            }else if(organizationNewsDO != null && certificationBatchDO == null){
                    if(StringUtils.isNotBlank(organizationNewsDO.getName())){
                        pdfName =  organizationNewsDO.getName() + "-证书信息";
                    }else{
                        pdfName = "考点证书信息";
                    }

            }else if(certificationBatchDO != null && organizationNewsDO == null){
                if(StringUtils.isNotBlank(certificationBatchDO.getName())){
                    pdfName = certificationBatchDO.getName() + "-证书信息";
                }else{
                    pdfName = "认证批次证书信息";
                }
            }else{
                pdfName = "所有证书信息";
            }

            try {
                this.creatPdf(pdfName,imgUrls);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            try {
                // path是指欲下载的文件的路径。
                File file = new File(ValuesUtil.localUrl + "/work/" + pdfName + ".pdf");
                String filepath = file.getPath();
//                // 取得文件名。
//                String filename = file.getName();
//                // 取得文件的后缀名。
//                String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

                // 以流的形式下载文件。
                InputStream fis = new BufferedInputStream(new FileInputStream(filepath));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
                response.addHeader("Content-Disposition", "attachment;filename=" + new String((pdfName + ".pdf").getBytes(), "iso-8859-1"));
                response.addHeader("Content-Length", "" + file.length());
                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                response.setContentType("application/octet-stream");
                toClient.write(buffer);
                toClient.flush();
                toClient.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }else {
            throw new IFastApiException(ApiEnumError.NOTBATCHSTU.getCodeStr());
        }
    }

    public void creatPdf(String pdfName,List<String> imgUrls) throws IOException, DocumentException {
        // 第一步，实例化一个document对象
        Rectangle pageSize = new Rectangle(1123F, 794F);
        Document document = new Document(pageSize, 50, 50, 0, 50);
        // 设置相关的参数
        ITextPdfUtil.setParameters(document, "开发者", "测试", "测试 开发者 调试", "lance", "lance");
        // 第二步，设置要到出的路径
        try {
            FileOutputStream out = new FileOutputStream(ValuesUtil.localUrl + "/work/" + pdfName + ".pdf");
            // 第三步，将pdf文件输出到磁盘
            PdfWriter writer = PdfWriter.getInstance(document, out);
            // 第四步，打开生成的pdf文件
            document.open();
            // 第五步，往pdf文档中添加证书图片
            for (int i = 0; i < imgUrls.size(); i++) {
                if(StringUtils.isNotBlank(imgUrls.get(i))){
                    Image image = Image.getInstance(imgUrls.get(i));
                    image.setAlignment(Element.ALIGN_CENTER);//设置元素居中
                    document.add(image);
                }else{
                    throw new IFastApiException(ApiEnumError.NOTBATCHSTU.getCodeStr());
                }
            }
            // 第八步，关闭document
            document.close();

            //文件输出至服务器
            String pdffilepath = ValuesUtil.localUrl + "\\work\\" + pdfName + ".pdf";
            ITextPdfUtil.doAddWaterMark(pdffilepath, pdfName, 38, "255, 200, 0", "4, 550", 10);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
